// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "Import/BDFImport/BulkData/Property/PCOMPParser.h"

#include "gtest/gtest.h"

#include "DataStructure/Common/Constant.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Property/IPCOMPService.h"

using SG::DataStructure::Common::TOLERANCE;
using namespace SG::DataStructure::FEM;
#include "Import/BDFImport/BDFParserBase.h"
using namespace SG::DBManager;
using namespace SG::Import;
extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;
extern std::vector<std::string>          dividedEntryInfo;

class PCOMPParserTest : public ::testing::Test
{
  public:
    static void SetUpTestSuite ()
    {
        DB_SERVICEFACTORY->ClearDatabase ();
    }
};

TEST_F (PCOMPParserTest, ParseEntry1)
{
    std::vector<std::string> Entry = { "PCOMP   13244825 .62             10000.  HOFF                   MEM",
                                       "         3457    .155    45.     YES     3457    .155    0.      YES",
                                       "         3457    .155    -45.    YES     3457    .155    90.     YES",
                                       "         3457    .155    90.     YES     3457    .155    -45.    YES",
                                       "         3457    .155    0.      YES     3457    .155    45.     YES" };
    BDF::divideBulkEntry (Entry, dividedEntryInfo);
    SG::Import::BDF::BULKDATA::ParsePCOMP (DB_SERVICEFACTORY, dividedEntryInfo);
    SG::DataStructure::FEM::PCOMPData data;

    ASSERT_TRUE (DB_SERVICEFACTORY->get<IPCOMPService> ()->FindById (13244825, data) == SG::DataStructure::Common::Status::STATUS_Success);

    ASSERT_TRUE (data.m_id == 13244825);
    ASSERT_NEAR (data.m_offset, 0.62, TOLERANCE);
    ASSERT_EQ (data.m_lam, SG::DataStructure::FEM::LaminateOptions::LaminateOption_MEM);
    ASSERT_TRUE (data.m_ft == 2);
    ASSERT_TRUE (data.m_secData.size () == 8);
    ASSERT_TRUE (data.m_secData[0].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[0].m_name == "");
    // ASSERT_TRUE (data.m_secData[0].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[0].m_theta == 45.0);
    ASSERT_TRUE (data.m_secData[0].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[1].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[1].m_name == "");
    // ASSERT_TRUE (data.m_secData[1].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[1].m_theta == 0);
    ASSERT_TRUE (data.m_secData[1].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[2].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[2].m_name == "");
    // ASSERT_TRUE (data.m_secData[2].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[2].m_theta == -45.0);
    ASSERT_TRUE (data.m_secData[2].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[3].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[3].m_name == "");
    // ASSERT_TRUE (data.m_secData[3].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[3].m_theta == 90);
    ASSERT_TRUE (data.m_secData[3].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[4].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[4].m_name == "");
    // ASSERT_TRUE (data.m_secData[4].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[4].m_theta == 90);
    ASSERT_TRUE (data.m_secData[4].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[5].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[5].m_name == "");
    // ASSERT_TRUE (data.m_secData[5].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[5].m_theta == -45);
    ASSERT_TRUE (data.m_secData[5].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[6].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[6].m_name == "");
    // ASSERT_TRUE (data.m_secData[6].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[6].m_theta == 0);
    ASSERT_TRUE (data.m_secData[6].m_thickness == 0.155);

    ASSERT_TRUE (data.m_secData[7].m_matId == 3457);
    // ASSERT_TRUE (data.m_secData[7].m_name == "");
    // ASSERT_TRUE (data.m_secData[7].m_nInteg == 3);
    ASSERT_TRUE (data.m_secData[7].m_theta == 45);
    ASSERT_TRUE (data.m_secData[7].m_thickness == 0.155);

    // std::cout << "结构体未实现强度相关数据\n";
}

TEST_F (PCOMPParserTest, ParseEntry2)
{  // PID Z0  NSM SB FT TREF GE LAM
    std::vector<std::string> Entry = { "PCOMP   30001           0.0     0.65E6  TSAI                    SYM",
                                       "        70      0.500   0.0     YES     70      0.500   90.     YES",
                                       "        70      0.500   45.     YES     70      0.500   -45.    YES" };
    BDF::divideBulkEntry (Entry, dividedEntryInfo);
    SG::Import::BDF::BULKDATA::ParsePCOMP (DB_SERVICEFACTORY, dividedEntryInfo);
    SG::DataStructure::FEM::PCOMPData data;

    ASSERT_TRUE (DB_SERVICEFACTORY->get<IPCOMPService> ()->FindById (30001, data) == SG::DataStructure::Common::Status::STATUS_Success);

    ASSERT_TRUE (data.m_id == 30001);
    ASSERT_NEAR (data.m_offset, -2, TOLERANCE);
    ASSERT_NEAR (data.m_nsm, 0.0, TOLERANCE);
    ASSERT_NEAR (data.m_sb, 0.65e+6, TOLERANCE);
    ASSERT_EQ (data.m_lam, SG::DataStructure::FEM::LaminateOptions::LaminateOption_SYM);
    ASSERT_TRUE (data.m_ft == 3);  // TSAI failure theory

    // Verify we have 4 plies
    ASSERT_TRUE (data.m_secData.size () == 4);

    // First ply: Material 70, thickness 0.500, angle 0.0, YES
    ASSERT_TRUE (data.m_secData[0].m_matId == 70);
    ASSERT_NEAR (data.m_secData[0].m_thickness, 0.500, TOLERANCE);
    ASSERT_NEAR (data.m_secData[0].m_theta, 0.0, TOLERANCE);

    // Second ply: Material 70, thickness 0.500, angle 90.0, YES
    ASSERT_TRUE (data.m_secData[1].m_matId == 70);
    ASSERT_NEAR (data.m_secData[1].m_thickness, 0.500, TOLERANCE);
    ASSERT_NEAR (data.m_secData[1].m_theta, 90.0, TOLERANCE);

    // Third ply: Material 70, thickness 0.500, angle 45.0, YES
    ASSERT_TRUE (data.m_secData[2].m_matId == 70);
    ASSERT_NEAR (data.m_secData[2].m_thickness, 0.500, TOLERANCE);
    ASSERT_NEAR (data.m_secData[2].m_theta, 45.0, TOLERANCE);

    // Fourth ply: Material 70, thickness 0.500, angle -45.0, YES
    ASSERT_TRUE (data.m_secData[3].m_matId == 70);
    ASSERT_NEAR (data.m_secData[3].m_thickness, 0.500, TOLERANCE);
    ASSERT_NEAR (data.m_secData[3].m_theta, -45.0, TOLERANCE);
}
